<template>
  <div class="app-container">
    <div ref="box" class="box" :style="{ height: BoxHeight + 'px' }">
      <div class="top">
        <el-select
          v-model="sourceId"
          style="width: 15%; margin-right: 15px"
          placeholder="请选择数据库"
          clearable
          @change="changeSource"
        >
          <el-option
            v-for="dict in listDatasource"
            :key="dict.dataSourceName"
            :label="dict.dataSourceName"
            :value="dict.id"
          />
        </el-select>

        <el-select
          v-model="databaseName"
          style="width: 15%; margin-right: 15px"
          placeholder="请选择源库"
          clearable
        >
          <el-option
            v-for="item in listTableData"
            :key="item"
            :label="item"
            :value="item"
          />
        </el-select>

        <el-button
          type="success"
          style="width: 10%"
          @click="executeSql"
        >+ 执行SQL</el-button>
        <el-button type="info" @click="handleHistory">执行历史</el-button>
      </div>
      <div class="middle">
        <div class="left">
          <ul
            v-if="sourceId && sourceDatabaseHistoryList.length > 0"
            class="databaseBox"
          >
            <li
              v-for="item in sourceDatabaseHistoryList"
              :key="item.createTime"
              class="database-item"
              @click="selectListdatabase(item)"
            >
              <a href="#" title="查看sql">
                <div class="sql-status" />
                <p>{{ item.dataSourceName }}</p>
                <pre class="historySql">{{ item.sqlContext }}</pre>
                <p style="color: #666; font-size: 12px">
                  执行时间：{{ item.createTime }}
                </p>
              </a>
              <!-- <a href="#" class="item-text" :title="item">{{ item }}</a> -->
            </li>
          </ul>
          <el-empty v-else description="暂无历史" :image-size="150" />
        </div>
        <div ref="right" class="right">
          <editor
            :key="offsetHeight"
            ref="aceEditor"
            v-model="sql"
            width="100%"
            :height="offsetHeight"
            lang="sql"
            theme="dracula"
            :options="{
              enableBasicAutocompletion: true,
              enableSnippets: true,
              enableLiveAutocompletion: true,
              showPrintMargin: false, //去除编辑器里的竖线
              tabSize: 4,
              fontSize: 16,
            }"
            @init="editorInit"
          />
          <div
            ref="historyEl"
            class="history"
            :style="{ height: historyBox + 'px' }"
          >
            <div class="line" @mousedown.stop.prevent="drag" />
            <div class="history-list">
              <div
                v-for="(item, index) in historyList"
                :key="index"
                class="history-item"
              >
                <div class="history-item-title">
                  <p
                    :style="{
                      color: item.status == 'success' ? '#fff' : 'red',
                    }"
                    class="history-item-title-text"
                  >
                    {{ item.createTime }}：{{ item.title }}
                  </p>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    <el-dialog title="sql查看" :visible.sync="dialogStackVisible" width="75%">
      <el-button
        style="margin-bottom: 10px"
        type="primary"
        @click="copyDdl"
      >复制</el-button>
      <editor
        ref="aceEditor"
        v-model="stackErrorsMsg"
        width="100%"
        :height="400"
        lang="sql"
        theme="dracula"
        :options="{
          enableBasicAutocompletion: true,
          enableSnippets: true,
          enableLiveAutocompletion: true,
          showPrintMargin: false, //去除编辑器里的竖线
          tabSize: 4,
          fontSize: 16,
          readOnly: true,
        }"
        @init="editorInit"
      />
      <span slot="footer" class="dialog-footer">
        <el-button
          type="primary"
          @click="dialogStackVisible = false"
        >确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import {
  listDatasourceInfo,
  databaseListData
} from '@/api/console/datasourceInfo'
import { sqlTaskExecuteSql, sqlTaskList } from '@/api/console/executeSql'

export default {
  name: 'ExecuteSql',
  components: { editor: require('vue2-ace-editor') },
  data() {
    return {
      stackErrorsMsg: '',
      dialogStackVisible: false,
      sourceId: null,
      databaseId: null,
      listDatasource: [],
      listTableData: [],
      active: null,
      offsetHeight: null,
      BoxHeight: null,
      sql: null,
      startWidth: 0,
      startHeight: 0,
      startX: 0,
      startY: 0,
      boxWidth: 0,
      historyBox: 140,
      dragging: false,
      historyList: [],
      rightBoxHeight: 0,
      databaseName: null,
      sourceDatabaseHistoryList: []
    }
  },
  async mounted() {
    const res = await listDatasourceInfo({
      pgNum: 1,
      pgSize: 999
    })
    this.listDatasource = res.rows
    this.offsetHeight = this.$refs.right.offsetHeight - this.historyBox
    this.BoxHeight = this.$refs.box.offsetHeight
    this.rightBoxHeight = this.$refs.right.offsetHeight
  },
  methods: {
    copyDdl() {
      const dom = document.createElement('input')
      dom.value = this.stackErrorsMsg
      document.body.appendChild(dom)
      dom.select()
      document.execCommand('copy')
      document.body.removeChild(dom)
      this.$message.success('复制成功')
    },
    handleHistory() {
      this.$router.push({
        path: '/sqlHistory/index'
      })
    },
    drag(e) {
      e.preventDefault()
      this.dragging = true
      const codeBoxEl = this.$refs.historyEl
      this.startHeight = codeBoxEl.offsetHeight
      this.startY = e.clientY
      document.addEventListener('mousemove', this.doDrag)
      document.addEventListener('mouseup', this.stopDrag)
    },
    doDrag(event) {
      if (this.dragging) {
        this.historyBox = this.startHeight + (event.clientY - this.startY) * -1
        this.offsetHeight = this.rightBoxHeight - this.historyBox
        if (this.historyBox >= this.rightBoxHeight - 80) {
          this.historyBox = this.rightBoxHeight - 80
          this.offsetHeight = 80
        }
        if (this.historyBox < 80) {
          this.historyBox = 80
          this.offsetHeight = this.rightBoxHeight - 80
        }
      }
    },
    stopDrag() {
      this.dragging = false
      document.removeEventListener('mousemove', this.doDrag)
      document.removeEventListener('mouseup', this.stopDrag)
    },
    editorInit() {
      // 初始化
      require('brace/ext/language_tools')
      require('brace/ext/beautify')
      require('brace/ext/error_marker')
      require('brace/ext/searchbox')
      require('brace/ext/split')
      require('brace/snippets/sql')
      require('brace/mode/sql')
      require('brace/theme/dracula')
    },
    createDatabase() {
      this.$router.push({
        path: '/datasourceInfo'
      })
    },
    selectListdatabase(item) {
      this.active = item
      this.stackErrorsMsg = item.sqlContext
      this.dialogStackVisible = true
    },
    removeSpaces(str) {
      return str.replace(/\s+/g, '')
    },
    async changeSource(v) {
      if (!v) {
        this.databaseName = null
        return
      }
      this.databaseId = v
      const item = this.listDatasource.find((item) => item.id == v)
      let res = await databaseListData({
        id: v
      })
      this.listTableData = res.data.data
      res = await sqlTaskList({
        pgNum: 1,
        pgSize: 999,
        dataSourceName: item.dataSourceName
      })
      this.sourceDatabaseHistoryList = res.rows
    },
    async executeSql() {
      const that = this
      if (!this.sourceId) {
        this.$message.warning('请选择数据库')
        return
      }
      if (this.removeSpaces(this.sql).length === 0) {
        return
      }
      try {
        this.$modal
          .confirm('是否确认执行SQL？')
          .then(function() {
            return sqlTaskExecuteSql({
              datasourceId: that.databaseId,
              sqlContext: that.sql,
              databaseName: that.databaseName
            })
          })
          .then(async(res) => {
            this.historyList.push({
              createTime: new Date().toLocaleString(),
              title: res.data.msg,
              status: res.data.code == '200' ? 'success' : 'error'
            })
            this.changeSource(this.databaseId)
            this.$nextTick(() => {
              const scrollElem = this.$refs.historyEl
              scrollElem.scrollTo({
                top: scrollElem.scrollHeight,
                behavior: 'smooth'
              })
            })
          })
      } catch (error) {
      }
    }
  }
}
</script>
<style lang="scss" scoped>
.app-container {
  height: 100%;
  min-width: 1100px;
}

.box {
  width: 100%;
  height: 100%;
  border: 1px solid #aaa;
  display: flex;
  flex-direction: column;

  .top {
    width: 100%;
    height: 45px;
    border-bottom: 1px solid #000;
    display: flex;
    align-items: center;
    padding: 0 15px;
  }

  .middle {
    height: calc(100% - 45px);
    display: flex;
  }

  .left {
    width: 250px;
    text-align: center;
    padding: 10px 0;
    background: rgba(249, 249, 249);

    .databaseBox {
      list-style-type: none;
      width: 100%;
      text-align: left;
      margin: 0 auto 10px auto;
      padding: 0;
      overflow-y: auto;
      height: 100%;

      p {
        margin: 0;
        padding: 0;
      }

      .database-item {
        padding: 8px;
        cursor: pointer;
        overflow: auto;
        width: 100%;
        border-bottom: 1px solid #ccc;
        position: relative;
        //  .sql-status {
        //   position: absolute;
        //   right: 15px;
        //   width: 7px;
        //   height: 7px;
        //   top: 5px;
        //   background-color: red;
        //   border-radius: 50%;
        // }
        .item-text {
          color: #444;
          font-size: 15px;
          overflow: hidden;
          white-space: nowrap;
          text-overflow: ellipsis;
          display: block;
          width: 100%;
          color: rgba($color: #111, $alpha: 0.8);
        }
      }

      .database-item:hover {
        background: rgba(240, 240, 240, 0.8);
      }
    }
    .notSourceIdTips {
      padding: 0 8px;
      text-align: left;
      p {
        letter-spacing: 1px;
        color: #444;
        font-size: 14px;
      }
    }
  }
  .right {
    width: 100%;
    height: 100%;
    position: relative;

    .history {
      height: 140px;
      background-color: #000;
      width: 100%;
      position: absolute;
      bottom: 0;
      overflow: auto;
      z-index: 999;
      border: 1px solid rgba(250, 250, 250, 0.6);

      .line {
        width: 100%;
        height: 3px;
      }

      .line:hover {
        background-color: rgb(0, 120, 212);
        cursor: row-resize;
      }
    }
  }
}

::v-deep .el-divider--horizontal {
  margin: 15px 0;
}

.active {
  background-color: rgb(180, 180, 180);

  a {
    color: #fff !important;
  }
}

.active:hover {
  background-color: rgb(180, 180, 180) !important;
}

.history-item-title-text {
  font-size: 14px;
  padding: 0 10px;
}

.historySql {
  white-space: nowrap; /* 不换行 */
  overflow: hidden; /* 隐藏溢出内容 */
  text-overflow: ellipsis;
  -webkit-line-clamp: 3;
  height: 20px;
}
</style>
